package io.gitee.zhangbinhub.acp.boot.component

import io.gitee.zhangbinhub.acp.boot.constant.AcpCoreConstant
import io.gitee.zhangbinhub.acp.boot.exceptions.AcpWebExceptionHandler
import io.gitee.zhangbinhub.acp.boot.http.HttpStatus
import io.gitee.zhangbinhub.acp.boot.log.LogAdapter
import io.gitee.zhangbinhub.acp.boot.tools.PackageTools
import org.noear.solon.core.handle.Context
import org.noear.solon.core.handle.Filter
import org.noear.solon.core.handle.FilterChain

class AcpBootGlobalFilter(
    private val logAdapter: LogAdapter, private val acpWebExceptionHandler: MutableList<AcpWebExceptionHandler>
) : Filter {
    override fun doFilter(ctx: Context, chain: FilterChain) {
        try {
            ctx.attrSet(AcpCoreConstant.HTTP_CLIENT_IP_KEY, ctx.realIp())
            chain.doFilter(ctx)
        } catch (ex: Throwable) {
            val errorResult = acpWebExceptionHandler
                .firstOrNull { handler -> handler.identify(ex) }
                ?.handle(ex)
                ?: PackageTools.buildErrorResult(HttpStatus.INTERNAL_SERVER_ERROR, ex.message)
            logAdapter.error(
                "HttpStatus[${errorResult.httpStatus.value()}]: ${errorResult.errorVo.errorDescription}", ex
            )
            ctx.status(errorResult.httpStatus.value())
            ctx.render(errorResult.errorVo)
        }
    }
}